﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using LispInterpretor;

namespace UnitTests
{
    [TestClass]
    public class TestEnvironment
    {
        [TestMethod]
        [ExpectedException(typeof(InvalidProgramException))]
        public void TestBadLookup()
        {
            var env = new LispInterpretor.Environment();

            env.Get("NoneExistent");
        }

        [TestMethod]
        public void TestBasicLookup()
        {
            var env = new LispInterpretor.Environment();

            env.Add("n", 3);

            Assert.AreEqual(3, env.Get("n"));
        }

        [TestMethod]
        public void TestShadowedLookup()
        {
            var firstEnv = new LispInterpretor.Environment();

            firstEnv.Add("n", 3);
            firstEnv.Add("p", 2);

            var secondEnv = new LispInterpretor.Environment(firstEnv);
            secondEnv.Add("n", 5);

            Assert.AreEqual(5, secondEnv.Get("n"));
            Assert.AreEqual(2, secondEnv.Get("p"));
        }

        [TestMethod]
        public void TestBasicExist()
        {
            var firstEnv = new LispInterpretor.Environment();
            
            Assert.AreEqual(false, firstEnv.Exists("n"));
            firstEnv.Add("n", 3);

            Assert.AreEqual(true, firstEnv.Exists("n"));
        }

        [TestMethod]
        public void TestShadowedExist()
        {
            var firstEnv = new LispInterpretor.Environment();
           
            firstEnv.Add("n", 3);
            firstEnv.Add("p", 2);

            var secondEnv = new LispInterpretor.Environment(firstEnv);
            secondEnv.Add("n", 4);

            Assert.AreEqual(true, secondEnv.Exists("n"));
            Assert.AreEqual(true, secondEnv.Exists("p"));
            Assert.AreEqual(false, secondEnv.Exists("o"));

        }

        [TestMethod]
        public void TestParentExist()
        {
            var firstEnv = new LispInterpretor.Environment();

            firstEnv.Add("n", 3);

            var secondEnv = new LispInterpretor.Environment(firstEnv);
            secondEnv.Add("n", 4);

            Assert.AreEqual(3, secondEnv.Parent.Get("n"));
        }
    }
}
